﻿using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Formats.Biff.OfficeArt;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal class ObjRecord : WorksheetLevelRecord
    {
        public ObjRecord(FtNts ftNts): this(FtCmoObjectType.Note)
        {
            this._nts = ftNts;
        }
        private ObjRecord(FtCmoObjectType type)
        {
            _cmo.ot = type;
        }

        protected override void ReadContent(BiffReaderContext context, int length)
        {
#if DEBUG
            var position = context.Reader.BaseStream.Position;
#endif
            var reader = context.Reader;
            _cmo.Read(reader);
            if (_cmo.ot == 0)
            {
                _gmo = new FtGmo();
                _gmo.Read(reader);
            }
            if (_cmo.ot == FtCmoObjectType.Picture)
            {
                _pictFormat = new FtCf();
                _pictFormat.Read(reader);
            }
            if (_cmo.ot == FtCmoObjectType.Picture)
            {
                _pictFlags = new FtPioGrbit();
                _pictFlags.Read(reader);
            }
            if (_cmo.ot == FtCmoObjectType.Checkbox || _cmo.ot == FtCmoObjectType.RadioButton)
            {
                _cbls = new FtCbls();
                _cbls.Read(reader);
            }
            if (_cmo.ot == FtCmoObjectType.RadioButton)
            {
                _rbo = new FtRbo();
                _rbo.Read(reader);
            }
            if (_cmo.ot == FtCmoObjectType.SpinControl | _cmo.ot == (FtCmoObjectType.Scrollbar) |
                _cmo.ot == (FtCmoObjectType.List) | _cmo.ot == (FtCmoObjectType.DropdownList))
            {
                _sbs = new FtSbs();
                _sbs.Read(reader);
            }
            if (_cmo.ot == (FtCmoObjectType.Note))
            {
                _nts = new FtNts();
                _nts.Read(reader);
            }
            ushort id = context.PeekUInt16();
            if (id == 0x0004)
            {
                macro = new FtMacro();
                macro.Read(reader);
            }
            if (_cmo.ot == (FtCmoObjectType.Picture))
            {
                if (context.PeekFtType() == FtType.FtPictFmla)
                {
                    _pictFmla = new FtPictFmla();
                    _pictFmla.Read(reader);
                }

            }
            if (_cmo.ot == (FtCmoObjectType.Checkbox) || _cmo.ot == FtCmoObjectType.RadioButton ||
                _cmo.ot == (FtCmoObjectType.SpinControl) || _cmo.ot == (FtCmoObjectType.Scrollbar) ||
                _cmo.ot == (FtCmoObjectType.List) || _cmo.ot == (FtCmoObjectType.DropdownList))
            {
                if (context.PeekFtType() == FtType.Sft)
                {
                    _linkFmla = new ObjLinkFmla();
                    _linkFmla.Read(reader);
                }
            }
            if (_cmo.ot == (FtCmoObjectType.Checkbox) || _cmo.ot == FtCmoObjectType.RadioButton)
            {
                _checkBox = new FtCblsData();
                _checkBox.Read(reader);
            }
            if (_cmo.ot == FtCmoObjectType.RadioButton)
            {
                _radioButton = new FtRboData();
                _radioButton.Read(reader);
            }
            if (_cmo.ot == (FtCmoObjectType.EditBox))
            {
                _edit = new FtEdoData();
                _edit.Read(reader);
            }
            if (_cmo.ot == (FtCmoObjectType.List) || _cmo.ot == (FtCmoObjectType.DropdownList))
            {
                _list = new FtLbsData();
                _list.Read(reader, _cmo.ot);
            }
            if (_cmo.ot == (FtCmoObjectType.GroupBox))
            {
                _gbo = new FtGboData();
                _gbo.Read(reader);
            }
            if (_cmo.ot != (FtCmoObjectType.List) && _cmo.ot != (FtCmoObjectType.DropdownList))
            {
                _reserved = (ushort)reader.ReadUInt32();
            }
        }

        internal override BiffRecordType RecordType
        {
            get { return BiffRecordType.Obj; }
        }

        public bool RequiresControlInfo
        {
            get { switch (this._cmo.ot)
            {
                case 0:
                case (FtCmoObjectType)5:
                case (FtCmoObjectType)7:
                case (FtCmoObjectType)11:
                case (FtCmoObjectType)12
                :
                case (FtCmoObjectType)14:
                    return true;
                default:
                    return false;
            }}
        }

        public OfficeArtClientData OfficeArtClientData { get; set; }

        private FtCbls _cbls;
        private FtCblsData _checkBox;
        private FtCmo _cmo;
        private FtEdoData _edit;
        private FtGboData _gbo;
        private FtGmo _gmo;
        private ObjLinkFmla _linkFmla;
        private FtLbsData _list;
        private FtNts _nts;
        private FtPioGrbit _pictFlags;
        private FtPictFmla _pictFmla;
        private FtCf _pictFormat;
        private FtRboData _radioButton;
        private FtRbo _rbo;
        private uint _reserved;
        private FtSbs _sbs;
        private FtMacro macro;

        public ObjRecord()
        {
        }

        internal override void Apply(BiffReaderWorksheetContext context)
        {
            if (context.ObjRecords.ContainsKey(_cmo.id))
            {
                Debug.WriteLine("problem, duplicate obj id");
                return;
            }
            context.ObjRecords.Add(this._cmo.id, this);
        }

        internal override void WriteContent(BiffWriterWorkbookContext context)
        {
            var writer = context.Writer;
            _cmo.Setup(context.GetObjIdFromObj(this));
            _cmo.Write(writer);
            if (_cmo.ot == 0)
            {
                _gmo.Write(writer);
            }
            if (_cmo.ot == FtCmoObjectType.Picture)
            {
                _pictFormat.Write(writer);
            }
            if (_cmo.ot == FtCmoObjectType.Picture)
            {
                _pictFlags.Write(writer);
            }
            if (_cmo.ot == FtCmoObjectType.Checkbox || _cmo.ot == FtCmoObjectType.RadioButton)
            {
                _cbls.Write(writer);
            }
            if (_cmo.ot == FtCmoObjectType.RadioButton)
            {
                _rbo.Write(writer);
            }
            if (_cmo.ot == FtCmoObjectType.SpinControl | _cmo.ot == (FtCmoObjectType.Scrollbar) |
                _cmo.ot == (FtCmoObjectType.List) | _cmo.ot == (FtCmoObjectType.DropdownList))
            {
                _sbs.Write(writer);
            }
            if (_cmo.ot == (FtCmoObjectType.Note))
            {
                _nts.Write(writer);
            }
            if (macro != null)
                macro.Write(writer);
            if (_cmo.ot == (FtCmoObjectType.Picture) && _pictFmla != null)
            {
                _pictFmla.Write(writer);
            }
            if (_cmo.ot == (FtCmoObjectType.Checkbox) || _cmo.ot == FtCmoObjectType.RadioButton ||
                _cmo.ot == (FtCmoObjectType.SpinControl) || _cmo.ot == (FtCmoObjectType.Scrollbar) ||
                _cmo.ot == (FtCmoObjectType.List) || _cmo.ot == (FtCmoObjectType.DropdownList))
            {
                if (_linkFmla != null)
                    _linkFmla.Write(writer);
            }
            if (_cmo.ot == (FtCmoObjectType.Checkbox) || _cmo.ot == FtCmoObjectType.RadioButton)
            {
                _checkBox.Write(writer);
            }
            if (_cmo.ot == FtCmoObjectType.RadioButton)
            {
                _radioButton.Write(writer);
            }
            if (_cmo.ot == (FtCmoObjectType.EditBox))
            {
                _edit.Write(writer);
            }
            if (_cmo.ot == (FtCmoObjectType.List) || _cmo.ot == (FtCmoObjectType.DropdownList))
            {
                _list.Write(writer);
            }
            if (_cmo.ot == (FtCmoObjectType.GroupBox))
            {
                _gbo.Write(writer);
            }
            if (_cmo.ot != (FtCmoObjectType.List) && _cmo.ot != (FtCmoObjectType.DropdownList))
            {
                writer.Write(_reserved);
            }

        }
    }
}